﻿using System;
using System.Collections.Generic;
using System.Windows.Forms;
using System.Text;
using System.IO;
using System.Data;
using System.Drawing;
using System.Data.SqlClient;
using FrameWorkSystem.BusinessLayer;
using FrameWorkSystem.BusinessLayer.DataLayer;
using CoreSystem;
namespace FrameWorkSystem
{
    public class CommonFunction
    {
        #region Load, cập nhật biến hệ thống
        public static string LoadSysVariable()
        {
            StringBuilder _errMsg = new StringBuilder();
            CoreSystem.SysVariable.GlobalVars = new SortedList<int, string>(100);
            Sys_variableSql objSysVariableDao = new Sys_variableSql();
            List<Sys_variable> Lst_Variable_Entities = objSysVariableDao.SelectAll();
            //
            foreach (Sys_variable _VarEntity in Lst_Variable_Entities)
                CoreSystem.SysVariable.GlobalVars.Add(_VarEntity.Record_id, _VarEntity.Realvalue);
            //// Lấy giá trị cho các biến
            //string Value_String;
            //#region Phần 1
            //if (_lstGlobalVar.TryGetValue(1, out Value_String))
            //    CoreSystem.SysVariable.Pk_Ten = Value_String;
            //if (_lstGlobalVar.TryGetValue(2, out Value_String))
            //    CoreSystem.SysVariable.Pk_Tieude = Value_String;
            //if (_lstGlobalVar.TryGetValue(3, out Value_String))
            //    CoreSystem.SysVariable.Pk_Diachi = Value_String;
            //if (_lstGlobalVar.TryGetValue(4, out Value_String))
            //    CoreSystem.SysVariable.Thaythuoc1_Ten = Value_String;
            //if (_lstGlobalVar.TryGetValue(5, out Value_String))
            //    CoreSystem.SysVariable.Thaythuoc1_Hocham = Value_String;
            //if (_lstGlobalVar.TryGetValue(6, out Value_String))
            //    CoreSystem.SysVariable.Donthuoc_Tieude = Value_String;
            //if (_lstGlobalVar.TryGetValue(7, out Value_String))
            //    CoreSystem.SysVariable.Donthuoc_Chuky = Value_String;
            //#endregion
 
            return _errMsg.ToString();
        }
        
        public static bool UpdateSysVariable(string varname, string var_value)
        {
            SqlConnection conn = new SqlConnection(CoreSystem.SysVariable.ConnectionString);
            SqlCommand cmd = new SqlCommand("UPDATE Sys_variable SET realvalue = @value WHERE variable = @varname", conn);
            cmd.Parameters.Add("@value", SqlDbType.NVarChar, 250).Value = var_value;
            cmd.Parameters.Add("@varname", SqlDbType.VarChar, 50).Value = varname;
            try
            {
                conn.Open();
                cmd.ExecuteNonQuery();
            }
            catch
            {
                throw new Exception("Cập nhật tham số không thành công");               
            }
            finally
            {
                cmd.Dispose();
                conn.Close();
            }
            return true;
        }
        #endregion       
        #region Hàm chuyển âm lịch <--> Dương lịch
        public static System.Globalization.VietnameseCalendar vnCalendar = new System.Globalization.VietnameseCalendar();
        public static DateTime Amlich2Duonglich(DateTime ngay)
        {
            return new DateTime(ngay.Year, ngay.Month, ngay.Day, vnCalendar);
        }
        public static DateTime Duonglich2Amlich(DateTime ngay)
        {
            int day, month, year;
            //VNIO_FrameWork.GlobalVariable.vnCalendar.AlgorithmType = System.Globalization.CalendarAlgorithmType.LunarCalendar;
            vnCalendar.FromDateTime(ngay, out year, out month, out day);
            return new DateTime(year, month, day);
        }
        public static string DateTime2LongString(DateTime date)
        {
            System.Text.StringBuilder bd = new System.Text.StringBuilder("Ngày <d> tháng <m> năm <y>");
            bd.Replace("<d>", date.Day.ToString());
            bd.Replace("<m>", date.Month.ToString());
            bd.Replace("<y>", date.Year.ToString());
            return bd.ToString();
        }
        #endregion
        #region Kiểm tra kết nối
        public static string CheckConnection(string configFile, bool xml)
        {
            if (xml)
                return LoadXml(configFile);
            else
                return LoadText(configFile);
        }
        private static string LoadXml(string configFile)
        {
            DataTable dtConnstr = new DataTable("SqlConnection");
            SqlConnection sqlConn = new SqlConnection();
            try
            {
                dtConnstr.ReadXml(configFile);
                for (int i = 0; i < dtConnstr.Rows.Count; i++)
                {
                    sqlConn.ConnectionString = dtConnstr.Rows[i]["ConnectionString"].ToString();

                    try
                    {
                        sqlConn.Open();
                        return sqlConn.ConnectionString;
                    }
                    catch { }
                }
            }
            catch
            {
                dtConnstr.Columns.Clear();
                dtConnstr.Columns.Add("ConnectionString", typeof(string));
            }
            finally
            {
                sqlConn.Dispose();
                dtConnstr.Dispose();
            }
            GUI.frmConnectionSetting frmConn = new FrameWorkSystem.GUI.frmConnectionSetting();
            if (frmConn.ShowDialog() == DialogResult.OK)
            {
                DataRow newrow = dtConnstr.Rows.Add(frmConn.ConnectionString);
                dtConnstr.WriteXml(configFile, XmlWriteMode.WriteSchema, false);
                return frmConn.ConnectionString;
            }
            return "";
        }
        private static string LoadText(string configFile)
        {
            FileStream stream = null;
            StreamReader reader = null;
            SqlConnection sqlConn = new SqlConnection();
            try
            {
                stream = new FileStream(configFile, FileMode.Open, FileAccess.Read);
                reader = new StreamReader(stream, Encoding.Unicode);                
                while(!reader.EndOfStream)
                {
                    sqlConn.ConnectionString = reader.ReadLine();

                    try
                    {
                        sqlConn.Open();
                        return sqlConn.ConnectionString;
                    }
                    catch { }
                }
            }
            catch
            {
               
            }
            finally
            {
                sqlConn.Dispose();
                if (stream != null) stream.Dispose();
                if (reader != null) reader.Dispose();
            }
            GUI.frmConnectionSetting frmConn = new FrameWorkSystem.GUI.frmConnectionSetting();
            if (frmConn.ShowDialog() == DialogResult.OK)
            {
                File.WriteAllText(configFile,frmConn.ConnectionString,Encoding.Unicode) ;                
                return frmConn.ConnectionString;
            }
            return "";
        }
        #endregion
        #region Đăng nhập chương trình
        public static bool Login()
        {
            bool loginOK = false;
            frmLogin logForm;
            Sys_UsersFactory objDao = new Sys_UsersFactory();
            Sys_Users objEntity;
            bool stop = false;

            do
            {
                logForm = new frmLogin(SysVariable.User_Name, "");
                stop = logForm.ShowDialog() == System.Windows.Forms.DialogResult.Cancel;
                // Kiểm tra user và password
                if (!stop)
                {
                    SysVariable.User_Name = logForm.txt_UserName.Text;
                    SysVariable.User_Pwd = logForm.txt_Password.Text;

                    objEntity = objDao.CheckUser(SysVariable.User_Name, SysVariable.User_Pwd, SysVariable.WorkingDate);

                    if (objEntity == null) continue;
                    // Nếu login thành công
                    loginOK = true;
                    SysVariable.User_FullName = objEntity.Full_Name;
                    SysVariable._IsEdit = objEntity.IsEdit;
                    SysVariable._isDelete = objEntity.IsDelete;
                    SysVariable._IsNew = objEntity.IsNew;

                    stop = true;
                }
            } while (!stop);
            return loginOK;
        }
        #endregion
        #region Load quyền của người dùng trên TreeView
        public static bool LoadUserPermission(System.Windows.Forms.TreeView twFunc)
        {
            // Load chức năng Treeview ra danh sách
            SortedList<string, TreeNode> lstFunc = ListFunction(twFunc);
            // Load Permission của User
            Sys_UserPermissionFactory objDao = new Sys_UserPermissionFactory();
            List<Sys_UserPermission> lstEntities = objDao.GetAllByType(FrameWorkSystem.PhanQuyen.TypeOfFunc.Tree, SysVariable.User_Name);

            int i;
            TreeNode func_node;
            for (i = 0; i < lstEntities.Count; i++)
            {
                if (lstFunc.TryGetValue(lstEntities[i].FuncName, out func_node))
                    func_node.Remove();
            }
            return true;
        }
        private static SortedList<string, TreeNode> ListFunction(TreeView twFunction)
        {
            SortedList<string, TreeNode> lstFuc = new SortedList<string, TreeNode>();
            Queue<TreeNode> _QNode = new Queue<TreeNode>(100);

            foreach (TreeNode node in twFunction.Nodes)
            {
                _QNode.Enqueue(node);
            }
            while (_QNode.Count != 0)
            {
                TreeNode dx = _QNode.Dequeue();
                lstFuc.Add(dx.Name, dx);
                foreach (TreeNode item in dx.Nodes)
                    _QNode.Enqueue(item);
            }
            return lstFuc;
        }
        #endregion
        #region Load quyền người dùng trên menu
        public static bool LoadUserPermission(System.Windows.Forms.MenuStrip mnuFunc)
        {
            // Load chức năng menu ra danh sách
            SortedList<string, ToolStripItem> lstFunc = ListMenuFuction(mnuFunc);
            // Load Permission của User
            Sys_UserPermissionFactory objDao = new Sys_UserPermissionFactory();
            List<Sys_UserPermission> lstEntities = objDao.GetAllByType(FrameWorkSystem.PhanQuyen.TypeOfFunc.Menu, SysVariable.User_Name);

            int i;
            ToolStripItem mmuItem;
            for (i = 0; i < lstEntities.Count; i++)
            {
                if (lstFunc.TryGetValue(lstEntities[i].FuncName, out mmuItem))
                {
                    mmuItem.Enabled = lstEntities[i].IsEnable;
                    mmuItem.Visible = lstEntities[i].IsVisible;
                }
            }
            return true;
        }
        public static SortedList<string, ToolStripItem> ListMenuFuction(MenuStrip mnuFuction)
        {
            Queue<ToolStripMenuItem> _QMnuItem = new Queue<ToolStripMenuItem>(mnuFuction.Items.Count);

            SortedList<string, ToolStripItem> lstFuc = new SortedList<string, ToolStripItem>();
            //            
            // Lấy các menu mức 1 để add vào root
            foreach (ToolStripMenuItem mnu in mnuFuction.Items)
            {
                lstFuc.Add(mnu.Name, mnu);
                _QMnuItem.Enqueue(mnu);
            }
            // 
            ToolStripMenuItem mnuParent, mnuChild;
            while (_QMnuItem.Count > 0)
            {
                mnuParent = _QMnuItem.Dequeue();
                foreach (ToolStripItem item in mnuParent.DropDownItems)
                {
                    lstFuc.Add(item.Name, item);

                    mnuChild = item as ToolStripMenuItem;
                    if (mnuChild != null)
                        _QMnuItem.Enqueue(mnuChild);
                }
            }
            //
            return lstFuc;
        }
        #endregion
        public static Color SelectColor()
        {
            ColorDialog dialog = new ColorDialog();
            dialog.FullOpen = true;
            if (dialog.ShowDialog() == DialogResult.OK)
                return dialog.Color;
            return Color.Empty;
        }
        public static string GetPrimaryKey(string tablename)
        {
            Sys_last_code_idFactory objSyscode = new Sys_last_code_idFactory();
            Sys_last_code_idKeys objKey = new Sys_last_code_idKeys(tablename);
            Sys_last_code_id objEntity = objSyscode.GetByPrimaryKey(objKey);
            if (objEntity != null)
                return objEntity.Prefix.Trim() + objEntity.Code_id.ToString().Trim().PadLeft(objEntity.Length - objEntity.Prefix.Length, '0') + objEntity.Suffix.Trim();
            else return "";
        }
        public static void UpdateLastPrimaryKey(string tablename)
        {
            DataLayerBase objDao = new DataLayerBase();
            string cmdStr = "UPDATE Sys_last_code_id SET Code_id = Code_id + 1 WHERE Table_name= @table_name";
            SqlParameter[] spParams = new SqlParameter[1];
            spParams[0] = new SqlParameter("@table_name", SqlDbType.VarChar, 50, ParameterDirection.Input, false, 0, 0, "", DataRowVersion.Proposed, tablename);           
            objDao.DoCommand(cmdStr, spParams);
        }
        public static string GetLastCodeID(string tablename)
        {
            Sys_last_code_idFactory objSyscode = new Sys_last_code_idFactory();
            Sys_last_code_idKeys objKey = new Sys_last_code_idKeys(tablename);
            Sys_last_code_id objEntity = objSyscode.GetByPrimaryKey(objKey);
            if (objEntity != null)
                return objEntity.Code_id.ToString().PadLeft(objEntity.Length, '0');
            else return "";
        }
        public static int GetCodeID(string tablename, string PrimaryKey)
        {
            Sys_last_code_idFactory objSyscode = new Sys_last_code_idFactory();
            Sys_last_code_idKeys objKey = new Sys_last_code_idKeys(tablename);
            Sys_last_code_id objEntity = objSyscode.GetByPrimaryKey(objKey);
            int id = 0;
            if (objEntity != null)
            {
                string id_str = PrimaryKey.Substring(objEntity.Prefix.Length, objEntity.Length);
                int.TryParse(id_str, out id);
            }
            return id;
        }
        public static void UpdateLastPrimaryKey(string tablename, string key)
        {
            DataLayerBase objDao = new DataLayerBase();
            SqlParameter[] spParams = new SqlParameter[2];
            spParams[0] = new SqlParameter("@table_name", SqlDbType.VarChar, 50, ParameterDirection.Input, false, 0, 0, "", DataRowVersion.Proposed, tablename);
            spParams[1] = new SqlParameter("@pk", SqlDbType.VarChar, 50, ParameterDirection.Input, false, 0, 0, "", DataRowVersion.Proposed, key);
            objDao.Do_SpSelect("sp_PrimaryKey_UpdateLast", spParams);
        }

        public static string SoTienBangChu(string _sotien)
        {            
            long SoTien;

            if (!long.TryParse(_sotien, out SoTien) ||
               (SoTien > 8999999999999999))
                return "Tiền không đúng định dạng";
            else
                return SoTienBangChu(SoTien);
        }
        public static string SoTienBangChu(long SoTien)
        {
            StringBuilder Result = new StringBuilder(100);
            if (SoTien < 0)
            {
                Result = new StringBuilder("Âm ",100);
                SoTien = -SoTien;
            }

            if (SoTien == 0) return "Không đồng";

            string[] ArrDonViTien = new string[6] { "", " nghìn", " triệu", " tỷ", " nghìn tỷ", " triệu tỷ" };

            #region Kiểm tra xem phải cắt 3 chữ số mấy lần

            int[] ViTri = new int[6];

            ViTri[5] = (int)(SoTien / 1000000000000000);
            SoTien = SoTien - long.Parse(ViTri[5].ToString()) * 1000000000000000;
            ViTri[4] = (int)(SoTien / 1000000000000);
            SoTien = SoTien - long.Parse(ViTri[4].ToString()) * +1000000000000;
            ViTri[3] = (int)(SoTien / 1000000000);
            SoTien = SoTien - long.Parse(ViTri[3].ToString()) * 1000000000;
            ViTri[2] = (int)(SoTien / 1000000);
            ViTri[1] = (int)((SoTien % 1000000) / 1000);
            ViTri[0] = (int)(SoTien % 1000);

            int SoLanDoc3ChuSo;

            if (ViTri[5] > 0)
            {
                SoLanDoc3ChuSo = 5;
            }
            else if (ViTri[4] > 0)
            {
                SoLanDoc3ChuSo = 4;
            }
            else if (ViTri[3] > 0)
            {
                SoLanDoc3ChuSo = 3;
            }
            else if (ViTri[2] > 0)
            {
                SoLanDoc3ChuSo = 2;
            }
            else if (ViTri[1] > 0)
            {
                SoLanDoc3ChuSo = 1;
            }
            else
            {
                SoLanDoc3ChuSo = 0;
            }
            #endregion

            StringBuilder tmp = new StringBuilder(10);

            for (int i = SoLanDoc3ChuSo; i >= 0; i--)
            {
                tmp = DocSoCoBaChuSo(ViTri[i]);
                Result.Append(tmp);
                if (ViTri[i] != 0)
                    Result.Append(ArrDonViTien[i]);
            }
            Result = Result.Replace(' ','\0',Result.Length-1,1);
            Result.Append(" đồng chẵn.");
            return Result[0].ToString().ToUpper()+ Result.ToString().Substring(1);
        }

        // Hàm đọc số có 3 chữ số
        private static StringBuilder DocSoCoBaChuSo(int baso)
        {
            string[] ChuSo = new string[10] { " không", " một", " hai", " ba", " bốn", " năm", " sáu", " bảy", " tám", " chín" };

            int tram, chuc, donvi;
            StringBuilder KetQua = new StringBuilder("");
            tram = (int)(baso / 100);
            chuc = (int)((baso % 100) / 10);
            donvi = baso % 10;

            if ((tram == 0) && (chuc == 0) && (donvi == 0))
                return new StringBuilder();

            if (tram != 0)
            {
                KetQua.Append(ChuSo[tram] + " trăm");
                if ((chuc == 0) && (donvi != 0))
                    KetQua.Append(" linh");
            }
            if ((chuc != 0) && (chuc != 1))
            {
                KetQua.Append(ChuSo[chuc] + " mươi");
                if ((chuc == 0) && (donvi != 0))
                    KetQua.Append(" linh");
            }
            if (chuc == 1)KetQua.Append(" mười");
            switch (donvi)
            {
                case 1:
                    if ((chuc != 0) && (chuc != 1))
                    {
                        KetQua.Append(" mốt");
                    }
                    else
                    {
                        KetQua.Append(ChuSo[donvi]);
                    }
                    break;

                case 5:
                    if (chuc == 0)
                    {
                        KetQua.Append(ChuSo[donvi]);
                    }
                    else
                    {
                        KetQua.Append(" lăm");
                    }
                    break;
                default:
                    if (donvi != 0)
                    {
                        KetQua.Append(ChuSo[donvi]);
                    }
                    break;
            }
            return KetQua;
        }    
    }
}
